/*
 * readline.c -
 * cezanne@clunix.com, 2005.3
 *
 * Copyright (c) 2001-2008 by Clunix Inc. All Rights Reserved.
 */

#include "edbtool2.h"

#include <signal.h>

extern FILE	*et2in;
extern void et2error(char *msg);

static char *rl_line = (char *)NULL;
static char *rl_start = (char *)NULL;
static int   rl_len = 0;

static char	*instr;
static int	instr_len;
static int	instr_ptr;

ECMBOOL	interactive = ECM_FALSE;
ECMBOOL	syntax_checking = ECM_FALSE;
ECMBOOL readline_done = ECM_FALSE;

void (*edbtool2_input)(char *buf, int *result, int max);

static void
edbtool2_readline(char *buf, int *result, int max)
{
	if (rl_len == 0) {
		char	*prompt;

		if (rl_start)
			ecm_free(rl_start);
		if (readline_done)
			rl_start = NULL;
		else {
			ecm_asprintf(&prompt, "edb:%s> ", cwd);
			rl_start = ecm_readline(prompt);
			ecm_free(prompt);
		}
		if (rl_start == NULL) {
			/* end of file */
			*result = 0;
			rl_len = 0;
			return;
		}
		rl_line = rl_start;
		rl_len = ecm_strlen(rl_line) + 1;
		rl_line[rl_len-1] = '\n';
		fflush(stdout);
	}

	if (rl_len <= max) {
		strncpy(buf, rl_line, rl_len);
		*result = rl_len;
		rl_len = 0;
	}
	else {
		strncpy (buf, rl_line, max);
		*result = max;
		rl_line += max;
		rl_len -= max;
	}
}

static void
edbtool2_read(char *buf, int *result, int max)
{
	ecm_size_t	nread = max;
	
	if (!ecm_read(ecm_fileno(et2in), buf, &nread)) {
		*result = -1;
	}
	else {
		*result = (int)nread;
	}
}

static void
edbtool2_readbuf(char *buf, int *result, int max)
{
	int	copycnt;

	if (instr_ptr < 0) {
		*result = 0;
		return;
	}
	if (instr_ptr == instr_len) {
		buf[0] = '\n';
		*result = 1;
		instr_ptr = -1;
		return;
	}
	copycnt = instr_len - instr_ptr;
	if (copycnt > max)
		copycnt = max;
	memcpy(buf, instr + instr_ptr, copycnt);
	instr_ptr += copycnt;
	*result = copycnt;
}

int
et2wrap(void)
{
	if (syntax_checking) {
		rewind(et2in);
		syntax_checking = ECM_FALSE;
		return 0;
	}
	return 1;
}

void
init_edbtool2_input(const char *filename, const char *buf)
{
	if (filename) {
		et2in = fopen(filename, "r");
		edbtool2_input = edbtool2_read;
		syntax_checking = ECM_TRUE;
	}
	else if (buf) {
		instr = (char *)buf;
		instr_len = ecm_strlen(buf);
		instr_ptr = 0;
		edbtool2_input = edbtool2_readbuf;
	}
	else {
		edbtool2_input = edbtool2_readline;
		interactive = ECM_TRUE;
	}
}
